using System.ComponentModel.DataAnnotations;
using OneCaps.Core.Enum;
using OneCaps.Core.Models;

namespace OneCaps.Core.Entity
{
    /// <summary>
    /// 停车记录实体
    /// </summary>
    public class ParkingRecord : BaseEntity<int>
    {
        /// <summary>
        /// 车辆ID
        /// </summary>
        public int VehicleId { get; set; }

        /// <summary>
        /// 车辆
        /// </summary>
        public virtual Vehicle Vehicle { get; set; } = null!;

        /// <summary>
        /// 车位ID
        /// </summary>
        public int ParkingSpaceId { get; set; }

        /// <summary>
        /// 车位
        /// </summary>
        public virtual ParkingSpace ParkingSpace { get; set; } = null!;

        /// <summary>
        /// 入场时间
        /// </summary>
        public DateTime EntryTime { get; set; }

        /// <summary>
        /// 出场时间
        /// </summary>
        public DateTime? ExitTime { get; set; }

        /// <summary>
        /// 停车状态
        /// </summary>
        public ParkingRecordStatus Status { get; set; } = ParkingRecordStatus.Parking;

        /// <summary>
        /// 车牌号（冗余字段，便于查询）
        /// </summary>
        [MaxLength(20)]
        public string LicensePlate { get; set; } = string.Empty;

        /// <summary>
        /// 车位编号（冗余字段，便于查询）
        /// </summary>
        [MaxLength(20)]
        public string SpaceNumber { get; set; } = string.Empty;

        /// <summary>
        /// 入场照片路径
        /// </summary>
        [MaxLength(500)]
        public string? EntryPhotoPath { get; set; }

        /// <summary>
        /// 出场照片路径
        /// </summary>
        [MaxLength(500)]
        public string? ExitPhotoPath { get; set; }

        /// <summary>
        /// 入场操作员
        /// </summary>
        [MaxLength(50)]
        public string? EntryOperator { get; set; }

        /// <summary>
        /// 出场操作员
        /// </summary>
        [MaxLength(50)]
        public string? ExitOperator { get; set; }

        /// <summary>
        /// 入场道闸编号
        /// </summary>
        [MaxLength(20)]
        public string? EntryGateNumber { get; set; }

        /// <summary>
        /// 出场道闸编号
        /// </summary>
        [MaxLength(20)]
        public string? ExitGateNumber { get; set; }

        /// <summary>
        /// 收费规则ID
        /// </summary>
        public int? BillingRuleId { get; set; }

        /// <summary>
        /// 收费规则
        /// </summary>
        public virtual BillingRule? BillingRule { get; set; }

        /// <summary>
        /// 应收费用
        /// </summary>
        public decimal Amount { get; set; } = 0;

        /// <summary>
        /// 实收费用
        /// </summary>
        public decimal ActualAmount { get; set; } = 0;

        /// <summary>
        /// 优惠金额
        /// </summary>
        public decimal DiscountAmount { get; set; } = 0;

        /// <summary>
        /// 支付方式
        /// </summary>
        public PaymentMethod? PaymentMethod { get; set; }

        /// <summary>
        /// 支付状态
        /// </summary>
        public PaymentStatus PaymentStatus { get; set; } = PaymentStatus.Unpaid;

        /// <summary>
        /// 支付时间
        /// </summary>
        public DateTime? PaymentTime { get; set; }

        /// <summary>
        /// 交易流水号
        /// </summary>
        [MaxLength(100)]
        public string? TransactionId { get; set; }

        /// <summary>
        /// 备注
        /// </summary>
        [MaxLength(500)]
        public string? Remarks { get; set; }

        // 领域方法
        /// <summary>
        /// 车辆入场
        /// </summary>
        public void VehicleEntry(DateTime entryTime, string? entryOperator = null, string? entryGateNumber = null)
        {
            if (Status != ParkingRecordStatus.Parking)
            {
                throw new InvalidOperationException("停车记录状态异常");
            }

            EntryTime = entryTime;
            EntryOperator = entryOperator;
            EntryGateNumber = entryGateNumber;
            UpdateTime = DateTime.Now;
        }

        /// <summary>
        /// 车辆出场
        /// </summary>
        public void VehicleExit(DateTime exitTime, string? exitOperator = null, string? exitGateNumber = null)
        {
            if (Status != ParkingRecordStatus.Parking)
            {
                throw new InvalidOperationException("停车记录状态异常");
            }

            ExitTime = exitTime;
            ExitOperator = exitOperator;
            ExitGateNumber = exitGateNumber;
            Status = ParkingRecordStatus.Completed;
            UpdateTime = DateTime.Now;
        }

        /// <summary>
        /// 计算停车时长
        /// </summary>
        public TimeSpan GetParkingDuration()
        {
            var endTime = ExitTime ?? DateTime.Now;
            return endTime - EntryTime;
        }

        /// <summary>
        /// 计算费用
        /// </summary>
        public Money CalculateFee()
        {
            if (BillingRule == null)
            {
                throw new InvalidOperationException("未设置收费规则");
            }

            var duration = GetParkingDuration();
            return BillingRule.CalculateFee(duration);
        }

        /// <summary>
        /// 设置费用
        /// </summary>
        public void SetAmount(Money amount)
        {
            Amount = amount.Amount;
            UpdateTime = DateTime.Now;
        }

        /// <summary>
        /// 支付
        /// </summary>
        public void Pay(Money actualAmount, PaymentMethod paymentMethod, string? transactionId = null)
        {
            if (PaymentStatus == PaymentStatus.Paid)
            {
                throw new InvalidOperationException("停车记录已支付");
            }

            ActualAmount = actualAmount.Amount;
            DiscountAmount = Amount - ActualAmount;
            PaymentMethod = paymentMethod;
            PaymentStatus = PaymentStatus.Paid;
            PaymentTime = DateTime.Now;
            TransactionId = transactionId;
            UpdateTime = DateTime.Now;
        }

        /// <summary>
        /// 取消支付
        /// </summary>
        public void CancelPayment()
        {
            if (PaymentStatus != PaymentStatus.Paid)
            {
                throw new InvalidOperationException("停车记录未支付，无法取消");
            }

            ActualAmount = 0;
            DiscountAmount = 0;
            PaymentMethod = null;
            PaymentStatus = PaymentStatus.Unpaid;
            PaymentTime = null;
            TransactionId = null;
            UpdateTime = DateTime.Now;
        }

        /// <summary>
        /// 检查是否超时
        /// </summary>
        public bool IsOverdue(TimeSpan maxDuration)
        {
            var duration = GetParkingDuration();
            return duration > maxDuration;
        }
    }
} 